#ifndef _TFSComApi_H_
#define _TFSComApi_H_

// {02F494FE-6ED4-4787-8D27-46EAFDC7C217}
DEFINE_GUID(CLSID_TFSServer, 0x2f494fe, 0x6ed4, 0x4787, 0x8d, 0x27, 0x46, 0xea, 0xfd, 0xc7, 0xc2, 0x17);

// {AE432687-84FD-48ef-B6E8-72DD0EE31F7A}
DEFINE_GUID(IID_ITFSServer, 0xae432687, 0x84fd, 0x48ef, 0xb6, 0xe8, 0x72, 0xdd, 0xe, 0xe3, 0x1f, 0x7a);

// {5676CC3A-372F-4fc3-84B3-D9EA87C11A04}
DEFINE_GUID(IID_ITFSWorkspace, 0x5676cc3a, 0x372f, 0x4fc3, 0x84, 0xb3, 0xd9, 0xea, 0x87, 0xc1, 0x1a, 0x4);

// {B8364ECA-D72A-4aa4-8838-9A3E37675B06}
DEFINE_GUID(IID_ITFSPendingChanges, 0xb8364eca, 0xd72a, 0x4aa4, 0x88, 0x38, 0x9a, 0x3e, 0x37, 0x67, 0x5b, 0x6);

//*************************************************************************************************
//*************************************************************************************************
enum TFSItemType
{
    TFSItemType_Any = 0,
    TFSItemType_Folder = 1,
    TFSItemType_File = 2
};

//*************************************************************************************************
//*************************************************************************************************
struct TFSItem
{
    BSTR ItemPath;
    TFSItemType ItemType;
    int ItemId;
    int ChangesetId;
    int DeletionId;
//TODO:    SAFEARRAY HashValue;
    _int64 ContentLength;
    int Encoding;

    //*********************************************************************************************
    //*********************************************************************************************
    void Delete()
    {
        if (ItemPath != NULL)
        {
            SysFreeString(ItemPath);
            ItemPath = NULL;
        }
    }
};

//*************************************************************************************************
//*************************************************************************************************
enum TFSPendingSetType
{
    TFSPendingSetType_Workspace = 0,
    TFSPendingSetType_Shelveset = 1
};

//*************************************************************************************************
//*************************************************************************************************
enum TFSChangeType
{
    TFSChangeType_None = 0,
    TFSChangeType_Add = 1,
    TFSChangeType_Edit = 2,
    TFSChangeType_Encoding = 4,
    TFSChangeType_Rename = 8,
    TFSChangeType_Delete = 16,
    TFSChangeType_Undelete = 32,
    TFSChangeType_Branch = 64,
    TFSChangeType_Merge = 128,
    TFSChangeType_Lock = 256
};

//*************************************************************************************************
//*************************************************************************************************
enum TFSLockLevel
{
    TFSLockLevel_None = 0,
    TFSLockLevel_Checkin = 1,
    TFSLockLevel_CheckOut = 2,
    TFSLockLevel_Unchanged = 3
};
 
//*************************************************************************************************
//*************************************************************************************************
struct TFSPendingChange
{
    int ChangeId;
    TFSChangeType ChangeType;
    BSTR ServerItemPath;
    TFSItemType ItemType;
    int ItemId;
    int ChangesetId;
    int DeletionId;
    TFSLockLevel LockLevel;
    DATE CreationDate;
//TODO:    SAFEARRAY HashValue;
    int Encoding;
    BSTR LocalItemPath;
    BSTR SourceServerItemPath;
    BSTR SourceLocalItemPath;
    BSTR WorkspaceName;
    BSTR WorkspaceOwnerName;
    BSTR WorkspaceComputer;
    TFSPendingSetType WorkspaceType;

    //*********************************************************************************************
    //*********************************************************************************************
    void Delete()
    {
        if (ServerItemPath != NULL)
        {
            SysFreeString(ServerItemPath);
            ServerItemPath = NULL;
        }
        if (LocalItemPath != NULL)
        {
            SysFreeString(LocalItemPath);
            LocalItemPath = NULL;
        }
        if (SourceServerItemPath != NULL)
        {
            SysFreeString(SourceServerItemPath);
            SourceServerItemPath = NULL;
        }
        if (SourceLocalItemPath != NULL)
        {
            SysFreeString(SourceLocalItemPath);
            SourceLocalItemPath = NULL;
        }
        if (WorkspaceName != NULL)
        {
            SysFreeString(WorkspaceName);
            WorkspaceName = NULL;
        }
        if (WorkspaceOwnerName != NULL)
        {
            SysFreeString(WorkspaceOwnerName);
            WorkspaceOwnerName = NULL;
        }
        if (WorkspaceComputer != NULL)
        {
            SysFreeString(WorkspaceComputer);
            WorkspaceComputer = NULL;
        }
    }
};

//*************************************************************************************************
//*************************************************************************************************
 enum TFSWorkingFolderType
{
    TFSWorkingFolderType_Map = 0,
    TFSWorkingFolderType_Cloak = 1
};

//*************************************************************************************************
//*************************************************************************************************
struct TFSWorkingFolder
{
    TFSWorkingFolderType Type;
    BSTR LocalPath;
    BSTR ServerItemPath;

    //*********************************************************************************************
    //*********************************************************************************************
    void Delete()
    {
        if (LocalPath != NULL)
        {
            SysFreeString(LocalPath);
            LocalPath = NULL;
        }
        if (ServerItemPath != NULL)
        {
            SysFreeString(ServerItemPath);
            ServerItemPath = NULL;
        }
    }
};

/* Definition of interface: ITFSPendingChanges */
#undef INTERFACE
#define INTERFACE ITFSPendingChanges

DECLARE_INTERFACE_(ITFSPendingChanges, IDispatch)
{
BEGIN_INTERFACE
#ifndef NO_BASEINTERFACE_FUNCS

    /* IUnknown methods */
    STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;
    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
    STDMETHOD_(ULONG, Release)(THIS) PURE;

    /* IDispatch methods */
    STDMETHOD(GetTypeInfoCount)(THIS_ UINT FAR* pctinfo) PURE;

    STDMETHOD(GetTypeInfo)(
      THIS_
      UINT itinfo,
      LCID lcid,
      ITypeInfo FAR* FAR* pptinfo) PURE;

    STDMETHOD(GetIDsOfNames)(
      THIS_
      REFIID riid,
      OLECHAR FAR* FAR* rgszNames,
      UINT cNames,
      LCID lcid,
      DISPID FAR* rgdispid) PURE;

    STDMETHOD(Invoke)(
      THIS_
      DISPID dispidMember,
      REFIID riid,
      LCID lcid,
      WORD wFlags,
      DISPPARAMS FAR* pdispparams,
      VARIANT FAR* pvarResult,
      EXCEPINFO FAR* pexcepinfo,
      UINT FAR* puArgErr) PURE;
#endif

    /* ITFSPendingChanges methods */
    STDMETHOD(get_Count)(THIS_ int *Count);
    STDMETHOD(GetChange)(THIS_ int index, TFSPendingChange *PendingChange);
};

/* Definition of interface: ITFSWorkspace */
#undef INTERFACE
#define INTERFACE ITFSWorkspace

DECLARE_INTERFACE_(ITFSWorkspace, IDispatch)
{
BEGIN_INTERFACE
#ifndef NO_BASEINTERFACE_FUNCS

    /* IUnknown methods */
    STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;
    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
    STDMETHOD_(ULONG, Release)(THIS) PURE;

    /* IDispatch methods */
    STDMETHOD(GetTypeInfoCount)(THIS_ UINT FAR* pctinfo) PURE;

    STDMETHOD(GetTypeInfo)(
      THIS_
      UINT itinfo,
      LCID lcid,
      ITypeInfo FAR* FAR* pptinfo) PURE;

    STDMETHOD(GetIDsOfNames)(
      THIS_
      REFIID riid,
      OLECHAR FAR* FAR* rgszNames,
      UINT cNames,
      LCID lcid,
      DISPID FAR* rgdispid) PURE;

    STDMETHOD(Invoke)(
      THIS_
      DISPID dispidMember,
      REFIID riid,
      LCID lcid,
      WORD wFlags,
      DISPPARAMS FAR* pdispparams,
      VARIANT FAR* pvarResult,
      EXCEPINFO FAR* pexcepinfo,
      UINT FAR* puArgErr) PURE;
#endif

    /* ITFSWorkspace methods */
    STDMETHOD(GetWorkingFolderForServerItem)(THIS_ BSTR ItemPath, TFSWorkingFolder *psWorkingFolder);
    STDMETHOD(SetWorkingFolder)(THIS_ BSTR ItemPath, BSTR LocalPath);
};

/* Definition of interface: ITFSServer */
#undef INTERFACE
#define INTERFACE ITFSServer

DECLARE_INTERFACE_(ITFSServer, IDispatch)
{
BEGIN_INTERFACE
#ifndef NO_BASEINTERFACE_FUNCS

    /* IUnknown methods */
    STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;
    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
    STDMETHOD_(ULONG, Release)(THIS) PURE;

    /* IDispatch methods */
    STDMETHOD(GetTypeInfoCount)(THIS_ UINT FAR* pctinfo) PURE;

    STDMETHOD(GetTypeInfo)(
      THIS_
      UINT itinfo,
      LCID lcid,
      ITypeInfo FAR* FAR* pptinfo) PURE;

    STDMETHOD(GetIDsOfNames)(
      THIS_
      REFIID riid,
      OLECHAR FAR* FAR* rgszNames,
      UINT cNames,
      LCID lcid,
      DISPID FAR* rgdispid) PURE;

    STDMETHOD(Invoke)(
      THIS_
      DISPID dispidMember,
      REFIID riid,
      LCID lcid,
      WORD wFlags,
      DISPPARAMS FAR* pdispparams,
      VARIANT FAR* pvarResult,
      EXCEPINFO FAR* pexcepinfo,
      UINT FAR* puArgErr) PURE;
#endif

    /* ITFSServer methods */
    STDMETHOD(Connect)(THIS_ BSTR Url, BSTR Username, BSTR Password) PURE;
    STDMETHOD(get_AuthenticatedUser)(THIS_ BSTR *AuthenticatedUser) PURE;
    STDMETHOD(GetItem)(THIS_ BSTR ItemPath, TFSItem *psItem) PURE;
    STDMETHOD(GetParentItem)(THIS_ BSTR ItemPath, TFSItem *psItem) PURE;
    STDMETHOD(GetWorkspace)(THIS_ BSTR name, BSTR owner, ITFSWorkspace **ppIWorkspace);
    STDMETHOD(CreateWorkspace)(THIS_ BSTR name, BSTR owner, BSTR comment, ITFSWorkspace **ppIWorkspace);
    STDMETHOD(GetPendingChanges)(THIS_ BSTR itemPath, ITFSPendingChanges **ppIPendingChanges);
};

#endif // _TFSComApi_H_